#!/bin/bash

# 数据网关部署脚本
# 作者: Data Gateway Team
# 版本: 1.0.0

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_debug() {
    echo -e "${BLUE}[DEBUG]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

# 显示帮助信息
show_help() {
    echo "数据网关部署脚本"
    echo ""
    echo "用法: $0 [选项]"
    echo ""
    echo "选项:"
    echo "  -h, --help              显示帮助信息"
    echo "  -e, --env ENV           部署环境 (dev/test/prod)"
    echo "  -v, --version VERSION   部署版本"
    echo "  -s, --start             启动服务"
    echo "  -S, --stop              停止服务"
    echo "  -r, --restart           重启服务"
    echo "  -u, --update            更新服务"
    echo "  -l, --logs              查看日志"
    echo "  -s, --status            查看状态"
    echo "  --scale NUM             扩展实例数量"
    echo "  --rollback              回滚到上一个版本"
    echo "  --backup                备份当前版本"
    echo "  --restore BACKUP        恢复备份"
    echo ""
    echo "示例:"
    echo "  $0 --env prod --version 1.0.1 --start    # 启动生产环境1.0.1版本"
    echo "  $0 --env test --update                    # 更新测试环境"
    echo "  $0 --env prod --restart                   # 重启生产环境"
    echo "  $0 --env prod --scale 3                   # 扩展生产环境到3个实例"
}

# 检查依赖
check_dependencies() {
    log_info "检查部署依赖..."
    
    # 检查Docker
    if ! command -v docker &> /dev/null; then
        log_error "Docker未安装或不在PATH中"
        exit 1
    fi
    log_info "Docker版本: $(docker --version)"
    
    # 检查Docker Compose
    if ! command -v docker-compose &> /dev/null; then
        log_error "Docker Compose未安装或不在PATH中"
        exit 1
    fi
    log_info "Docker Compose版本: $(docker-compose --version)"
    
    # 检查curl
    if ! command -v curl &> /dev/null; then
        log_error "curl未安装或不在PATH中"
        exit 1
    fi
    
    log_info "依赖检查完成"
}

# 检查环境配置
check_environment() {
    log_info "检查环境配置..."
    
    if [ -z "$DEPLOY_ENV" ]; then
        log_error "请指定部署环境 (--env dev/test/prod)"
        exit 1
    fi
    
    # 检查环境配置文件
    env_file="docker-compose.${DEPLOY_ENV}.yml"
    if [ ! -f "$env_file" ]; then
        log_warn "环境配置文件不存在: $env_file，使用默认配置"
        env_file="docker-compose.yml"
    fi
    
    if [ ! -f "$env_file" ]; then
        log_error "Docker Compose配置文件不存在: $env_file"
        exit 1
    fi
    
    log_info "使用配置文件: $env_file"
    export COMPOSE_FILE="$env_file"
}

# 启动服务
start_services() {
    log_info "启动服务..."
    
    # 检查服务是否已运行
    if docker-compose ps | grep -q "Up"; then
        log_warn "服务已在运行，请先停止或使用 --restart"
        return 1
    fi
    
    # 启动服务
    docker-compose up -d
    
    # 等待服务启动
    log_info "等待服务启动..."
    sleep 30
    
    # 检查服务状态
    if check_service_health; then
        log_info "服务启动成功"
    else
        log_error "服务启动失败"
        return 1
    fi
}

# 停止服务
stop_services() {
    log_info "停止服务..."
    
    docker-compose down
    
    log_info "服务已停止"
}

# 重启服务
restart_services() {
    log_info "重启服务..."
    
    stop_services
    sleep 5
    start_services
}

# 更新服务
update_services() {
    log_info "更新服务..."
    
    # 拉取最新镜像
    log_info "拉取最新镜像..."
    docker-compose pull
    
    # 重新构建镜像（如果需要）
    if [ -n "$VERSION" ]; then
        log_info "构建指定版本镜像: $VERSION"
        docker-compose build --no-cache
    fi
    
    # 停止旧服务
    log_info "停止旧服务..."
    docker-compose down
    
    # 启动新服务
    log_info "启动新服务..."
    docker-compose up -d
    
    # 等待服务启动
    log_info "等待服务启动..."
    sleep 30
    
    # 检查服务状态
    if check_service_health; then
        log_info "服务更新成功"
    else
        log_error "服务更新失败"
        return 1
    fi
}

# 扩展服务
scale_services() {
    log_info "扩展服务到 $SCALE_NUM 个实例..."
    
    if [ -z "$SCALE_NUM" ]; then
        log_error "请指定扩展数量 (--scale NUM)"
        exit 1
    fi
    
    docker-compose up -d --scale data-gateway=$SCALE_NUM
    
    log_info "服务已扩展到 $SCALE_NUM 个实例"
}

# 查看日志
view_logs() {
    log_info "查看服务日志..."
    
    docker-compose logs -f data-gateway
}

# 查看状态
view_status() {
    log_info "查看服务状态..."
    
    echo "=== Docker Compose 服务状态 ==="
    docker-compose ps
    
    echo ""
    echo "=== 数据网关健康状态 ==="
    if check_service_health; then
        echo "✅ 服务健康"
    else
        echo "❌ 服务不健康"
    fi
    
    echo ""
    echo "=== 资源使用情况 ==="
    docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
}

# 检查服务健康状态
check_service_health() {
    local max_attempts=30
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        if curl -f http://localhost:8080/data-gateway/api/health/status > /dev/null 2>&1; then
            return 0
        fi
        
        log_info "等待服务健康检查... ($attempt/$max_attempts)"
        sleep 10
        ((attempt++))
    done
    
    return 1
}

# 备份当前版本
backup_current() {
    log_info "备份当前版本..."
    
    local backup_dir="backups/$(date +%Y%m%d_%H%M%S)"
    mkdir -p "$backup_dir"
    
    # 备份配置文件
    cp docker-compose*.yml "$backup_dir/" 2>/dev/null || true
    cp Dockerfile "$backup_dir/" 2>/dev/null || true
    
    # 备份数据卷
    docker run --rm -v data-gateway-data:/data -v "$(pwd)/$backup_dir":/backup alpine tar czf /backup/data.tar.gz -C /data .
    
    log_info "备份完成: $backup_dir"
}

# 回滚到上一个版本
rollback_version() {
    log_info "回滚到上一个版本..."
    
    # 查找最新的备份
    local latest_backup=$(ls -t backups/ | head -n 1)
    
    if [ -z "$latest_backup" ]; then
        log_error "没有找到备份文件"
        exit 1
    fi
    
    log_info "回滚到备份: $latest_backup"
    
    # 停止当前服务
    stop_services
    
    # 恢复配置
    cp "backups/$latest_backup"/*.yml . 2>/dev/null || true
    
    # 恢复数据
    docker run --rm -v data-gateway-data:/data -v "$(pwd)/backups/$latest_backup":/backup alpine tar xzf /backup/data.tar.gz -C /data
    
    # 启动服务
    start_services
    
    log_info "回滚完成"
}

# 恢复备份
restore_backup() {
    log_info "恢复备份: $RESTORE_BACKUP"
    
    if [ -z "$RESTORE_BACKUP" ]; then
        log_error "请指定备份目录 (--restore BACKUP)"
        exit 1
    fi
    
    if [ ! -d "backups/$RESTORE_BACKUP" ]; then
        log_error "备份目录不存在: backups/$RESTORE_BACKUP"
        exit 1
    fi
    
    # 停止当前服务
    stop_services
    
    # 恢复配置
    cp "backups/$RESTORE_BACKUP"/*.yml . 2>/dev/null || true
    
    # 恢复数据
    docker run --rm -v data-gateway-data:/data -v "$(pwd)/backups/$RESTORE_BACKUP":/backup alpine tar xzf /backup/data.tar.gz -C /data
    
    # 启动服务
    start_services
    
    log_info "恢复完成"
}

# 清理资源
cleanup_resources() {
    log_info "清理资源..."
    
    # 清理未使用的镜像
    docker image prune -f
    
    # 清理未使用的容器
    docker container prune -f
    
    # 清理未使用的网络
    docker network prune -f
    
    # 清理未使用的数据卷
    docker volume prune -f
    
    log_info "资源清理完成"
}

# 主函数
main() {
    # 默认参数
    DEPLOY_ENV=""
    VERSION=""
    START_SERVICE=false
    STOP_SERVICE=false
    RESTART_SERVICE=false
    UPDATE_SERVICE=false
    VIEW_LOGS=false
    VIEW_STATUS=false
    SCALE_NUM=""
    ROLLBACK=false
    BACKUP=false
    RESTORE_BACKUP=""
    
    # 解析命令行参数
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            -e|--env)
                DEPLOY_ENV="$2"
                shift 2
                ;;
            -v|--version)
                VERSION="$2"
                shift 2
                ;;
            -s|--start)
                START_SERVICE=true
                shift
                ;;
            -S|--stop)
                STOP_SERVICE=true
                shift
                ;;
            -r|--restart)
                RESTART_SERVICE=true
                shift
                ;;
            -u|--update)
                UPDATE_SERVICE=true
                shift
                ;;
            -l|--logs)
                VIEW_LOGS=true
                shift
                ;;
            --status)
                VIEW_STATUS=true
                shift
                ;;
            --scale)
                SCALE_NUM="$2"
                shift 2
                ;;
            --rollback)
                ROLLBACK=true
                shift
                ;;
            --backup)
                BACKUP=true
                shift
                ;;
            --restore)
                RESTORE_BACKUP="$2"
                shift 2
                ;;
            *)
                log_error "未知参数: $1"
                show_help
                exit 1
                ;;
        esac
    done
    
    # 检查依赖
    check_dependencies
    
    # 检查环境配置
    check_environment
    
    # 执行操作
    if [ "$START_SERVICE" = true ]; then
        start_services
    elif [ "$STOP_SERVICE" = true ]; then
        stop_services
    elif [ "$RESTART_SERVICE" = true ]; then
        restart_services
    elif [ "$UPDATE_SERVICE" = true ]; then
        update_services
    elif [ "$VIEW_LOGS" = true ]; then
        view_logs
    elif [ "$VIEW_STATUS" = true ]; then
        view_status
    elif [ -n "$SCALE_NUM" ]; then
        scale_services
    elif [ "$ROLLBACK" = true ]; then
        rollback_version
    elif [ "$BACKUP" = true ]; then
        backup_current
    elif [ -n "$RESTORE_BACKUP" ]; then
        restore_backup
    else
        log_error "请指定操作"
        show_help
        exit 1
    fi
}

# 执行主函数
main "$@"
